(function ($) {
    function calcDisableClasses(oSettings) {
        var start = oSettings._iDisplayStart;
        var length = oSettings._iDisplayLength;
        var visibleRecords = oSettings.fnRecordsDisplay();
        var all = length === -1;

        // Gordey Doronin: Re-used this code from main jQuery.dataTables source code. To be consistent.
        var page = all ? 0 : Math.ceil(start / length);
        var pages = all ? 1 : Math.ceil(visibleRecords / length);

        var disableFirstPrevClass = (page > 0 ? '' : oSettings.oClasses.sPageButtonDisabled);
        var disableNextLastClass = (page < pages - 1 ? '' : oSettings.oClasses.sPageButtonDisabled);

        return {
//            'first': disableFirstPrevClass,
            'previous': disableFirstPrevClass,
            'next': disableNextLastClass
//            'last': disableNextLastClass
        };
    }

    function calcCurrentPage(oSettings) {
        return Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
    }

    function calcPages(oSettings) {
        return Math.ceil(oSettings.fnRecordsDisplay() / oSettings._iDisplayLength);
    }

//    var firstClassName = 'first';
    var previousClassName = 'previous';
    var nextClassName = 'next';
//    var lastClassName = 'last';

    var paginateClassName = 'paginate_button ';
    var paginateOfClassName = 'paginate_of';
    var paginatePageClassName = 'paginate_page';
    var paginateInputClassName = 'paginate_input';

    $.fn.dataTableExt.oPagination.input = {
        'fnInit': function (oSettings, nPaging, fnCallbackDraw) {
        	var nPageUl = document.createElement('ul');
//        	var nFirstLi = document.createElement('li');
//            var nFirst = document.createElement('a');
            var nPreviousLi = document.createElement('li');
            var nPrevious = document.createElement('a');
            nPrevious.href='javascript:;';
            var nNextLi = document.createElement('li');
            var nNext = document.createElement('a');
            nNext.href='javascript:;';
//            var nLastLi = document.createElement('li');
//            var nLast = document.createElement('a');

            var nInputLi = document.createElement('li');
            var nPageLi = document.createElement('li');
            var nOfLi = document.createElement('li');
            var nInput = document.createElement('input');
            nInput.size='5';
            var nPage = document.createElement('lable');
            var nOf = document.createElement('lable');

            var language = oSettings.oLanguage.oPaginate;
            var classes = oSettings.oClasses;

//            nFirst.innerHTML = language.sFirst;
            nPrevious.innerHTML = language.sPrevious;
            nNext.innerHTML = language.sNext;
//            nLast.innerHTML = language.sLast;

            nPageUl.className = 'pagination';
//            nFirstLi.className = firstClassName + ' ' + classes.sPageButton;
            nPageLi.className = 'pull-left';
            nInputLi.className =paginateInputClassName+ ' pull-left';
            nOfLi.className = paginateOfClassName + ' ' + classes.sPageButton + ' pull-left';
            nPreviousLi.className = previousClassName + ' ' + classes.sPageButton;
            nNextLi.className = nextClassName + ' ' + classes.sPageButton;
//            nLastLi.className = lastClassName + ' ' + classes.sPageButton;

            nOf.className = paginateOfClassName + ' label';
            nPage.className = paginatePageClassName + ' label';
            nInput.className ='form-control';

            if (oSettings.sTableId !== '') {
                nPaging.setAttribute('id', oSettings.sTableId + '_' + paginateClassName);
//                nFirstLi.setAttribute('id', oSettings.sTableId + '_' + firstClassName);
                nPreviousLi.setAttribute('id', oSettings.sTableId + '_' + previousClassName);
                nNextLi.setAttribute('id', oSettings.sTableId + '_' + nextClassName);
//                nLastLi.setAttribute('id', oSettings.sTableId + '_' + lastClassName);
            }

            nInput.type = 'text';
            nPage.innerHTML = '第';
            nPaging.appendChild(nPage);
            nPaging.appendChild(nInput);
            nPaging.appendChild(nOf);

            nInputLi.appendChild(nInput);
            nPageLi.appendChild(nPage);
            nOfLi.appendChild(nOf);

            nPageUl.appendChild(nPageLi);
            nPageUl.appendChild(nInputLi);
            nPageUl.appendChild(nOfLi);

//            nPageUl.appendChild(nPage);
//            nPageUl.appendChild(nInput);
//            nPageUl.appendChild(nOf);

//            nFirstLi.appendChild(nFirst);
            nPreviousLi.appendChild(nPrevious);
            nNextLi.appendChild(nNext);
//            nLastLi.appendChild(nLast);

//            nPageUl.appendChild(nFirstLi);
            nPageUl.appendChild(nPreviousLi);
            nPageUl.appendChild(nNextLi);
//            nPageUl.appendChild(nLastLi);

            nPaging.appendChild(nPageUl);

//            $(nFirst).click(function() {
//                var iCurrentPage = calcCurrentPage(oSettings);
//                if (iCurrentPage !== 1) {
//                    oSettings.oApi._fnPageChange(oSettings, 'first');
//                    fnCallbackDraw(oSettings);
//                }
//            });

            $(nPrevious).click(function() {
                var iCurrentPage = calcCurrentPage(oSettings);
                if (iCurrentPage !== 1) {
                    oSettings.oApi._fnPageChange(oSettings, 'previous');
                    fnCallbackDraw(oSettings);
                }
            });

            $(nNext).click(function() {
                var iCurrentPage = calcCurrentPage(oSettings);
                if (iCurrentPage !== calcPages(oSettings)) {
                    oSettings.oApi._fnPageChange(oSettings, 'next');
                    fnCallbackDraw(oSettings);
                }
            });

//            $(nLast).click(function() {
//                var iCurrentPage = calcCurrentPage(oSettings);
//                if (iCurrentPage !== calcPages(oSettings)) {
//                    oSettings.oApi._fnPageChange(oSettings, 'last');
//                    fnCallbackDraw(oSettings);
//                }
//            });

            $(nInput).keyup(function (e) {
                // 38 = up arrow, 39 = right arrow
                if (e.which === 38 || e.which === 39) {
                    this.value++;
                }
                // 37 = left arrow, 40 = down arrow
                else if ((e.which === 37 || e.which === 40) && this.value > 1) {
                    this.value--;
                }

                if (this.value === '' || this.value.match(/[^0-9]/)) {
                    /* Nothing entered or non-numeric character */
                    this.value = this.value.replace(/[^\d]/g, ''); // don't even allow anything but digits
                    return;
                }

                var iPages = calcPages(oSettings);
                var iNewStart
                if (iPages < this.value) {
                	iNewStart = oSettings._iDisplayLength * (iPages - 1);
                } else {
                	iNewStart = oSettings._iDisplayLength * (this.value - 1);
                    if (iNewStart < 0) {
                        iNewStart = 0;
                    }
                    if (iNewStart >= oSettings.fnRecordsDisplay()) {
                        iNewStart = (Math.ceil((oSettings.fnRecordsDisplay() - 1) / oSettings._iDisplayLength) - 1) * oSettings._iDisplayLength;
                    }
                }

                oSettings._iDisplayStart = iNewStart;
                fnCallbackDraw(oSettings);
            });

            // Take the brutal approach to cancelling text selection.
//            $('a', nPaging).bind('mousedown', function () { return false; });
//            $('a', nPaging).bind('selectstart', function() { return false; });

            // If we can't page anyway, might as well not show it.
            var iPages = calcPages(oSettings);
//            if (iPages <= 1) {
//                $(nPaging).hide();
//            }
        },

        'fnUpdate': function (oSettings) {
            if (!oSettings.aanFeatures.p) {
                return;
            }

            var iPages = calcPages(oSettings);
            var iCurrentPage = calcCurrentPage(oSettings);

            var an = oSettings.aanFeatures.p;
            if (iPages <= 1) // hide paging when we can't page
            {
                $(an).hide();
                return;
            }

            var disableClasses = calcDisableClasses(oSettings);

            $(an).show();

            // Enable/Disable `first` button.
//            $(an).children('.pagination').children('.' + firstClassName)
//                .removeClass(oSettings.oClasses.sPageButtonDisabled)
//                .addClass(disableClasses[firstClassName]);

            // Enable/Disable `prev` button.
            $(an).children('.pagination').children('.' + previousClassName)
                .removeClass(oSettings.oClasses.sPageButtonDisabled)
                .addClass(disableClasses[previousClassName]);

            // Enable/Disable `next` button.
            $(an).children('.pagination').children('.' + nextClassName)
                .removeClass(oSettings.oClasses.sPageButtonDisabled)
                .addClass(disableClasses[nextClassName]);

            // Enable/Disable `last` button.
//            $(an).children('.pagination').children('.' + lastClassName)
//                .removeClass(oSettings.oClasses.sPageButtonDisabled)
//                .addClass(disableClasses[lastClassName]);

            // Paginate of N pages text
            $(an).children('.pagination').children('.' + paginateOfClassName).children('lable').html('页，共' + iPages+'页');
            //var anPage = document.createElement('span');
            //anPage.innerHTML=' 页 ，共' + iPages+'页';
            //var pageOf = $(an).children('.pagination').children('.' + paginateOfClassName);
            //pageOf.appendChild(anPage);

            // Current page numer input value
            $(an).children('.pagination').children('.' + paginateInputClassName).children('input').val(iCurrentPage);
        }
    };
})(jQuery);